import QtQuick 2.15
import QtQuick.Controls 2.15

ApplicationWindow {
    id: main
    visible: true
    width: 800
    height: 600
    title: "轨道显示程序"

    property string currentShape: "circle"
    property bool isOuterTangent: true  // 默认外切
    property int wheelRadius: 50
    property real orbitRadiusX: 150
    property real orbitRadiusY: 150
    property real wheelSpeed: 1.0
    property int wheelHoleRadius: 1
    property color wheelHoleColor: "green"
    property real wheelHoleDistance: 0

    Canvas {
        id: traceCanvas
        anchors.centerIn: parent
        width: Math.max(800, (orbitRadiusX + wheelRadius + wheelHoleDistance + wheelHoleRadius) * (currentShape === "circle" ? 3.0 : 2.5))
        height: Math.max(800, (orbitRadiusY + wheelRadius + wheelHoleDistance + wheelHoleRadius) * (currentShape === "circle" ? 4.0 : 3.0))
        z: -1

        property real lastX: 0
        property real lastY: 0

        function clearTrace() {
            if (!available) {
                return
            }

            var ctx = getContext("2d")
            if (ctx) {
                ctx.fillStyle = "#f0f0f0"
                ctx.fillRect(0, 0, width, height)
                requestPaint()
                
                // 重置起始点
                var holeCenterInWheel = wheel.holeCenterInWheel()
                var globalPos = wheel.mapToItem(traceCanvas, holeCenterInWheel.x, holeCenterInWheel.y)
                lastX = globalPos.x
                lastY = globalPos.y
            }
        }

        onPaint: {
            // 仅初始化时绘制背景
            var ctx = getContext("2d")
            if (!painted) {
                ctx.fillStyle = "#f0f0f0"
                ctx.fillRect(0, 0, width, height)

                var holeCenterInWheel = wheel.holeCenterInWheel()
                var globalPos = wheel.mapToItem(traceCanvas, holeCenterInWheel.x, holeCenterInWheel.y)
                lastX = globalPos.x
                lastY = globalPos.y

                painted = true
            }
        }

        property bool painted: false
    }
    Rectangle {
        id: container
        anchors.centerIn: parent
        width: (orbitRadiusX + wheelRadius) * 2 + 20  // 添加10px边距
        height: (orbitRadiusY + wheelRadius) * 2 + 20
        color: "transparent"

        Canvas {
            id: orbitCanvas
            anchors.fill: parent
            property var orbitPoints: []
            
            function updateOrbitPoints() {
                var points = []
                var steps = 360
                var centerX = width/2
                var centerY = height/2
                
                for (var i = 0; i <= steps; i++) {
                    var angle = i * 2 * Math.PI / steps
                    if (currentShape === "circle") {
                        points.push(Qt.point(
                            centerX + orbitRadiusX * Math.cos(angle),
                            centerY + orbitRadiusX * Math.sin(angle)
                        ))
                    } else {
                        points.push(Qt.point(
                            centerX + orbitRadiusX * Math.cos(angle),
                            centerY + orbitRadiusY * Math.sin(angle)
                        ))
                    }
                }
                orbitPoints = points
                requestPaint()
            }

            onPaint: {
                var ctx = getContext("2d")
                ctx.reset()
                ctx.clearRect(0, 0, width, height)
                ctx.strokeStyle = "blue"
                ctx.lineWidth = 3

                ctx.beginPath()
                if (orbitPoints.length > 0) {
                    ctx.moveTo(orbitPoints[0].x, orbitPoints[0].y)
                    for (var i = 1; i < orbitPoints.length; i++) {
                        ctx.lineTo(orbitPoints[i].x, orbitPoints[i].y)
                    }
                }
                ctx.stroke()
            }

            Component.onCompleted: updateOrbitPoints()
            onWidthChanged: updateOrbitPoints()
            onHeightChanged: updateOrbitPoints()
        }
    }
    Wheel {
        id: wheel
        property real orbitRadiusX: main ? main.orbitRadiusX : 150
        property real orbitRadiusY: main ? (currentShape === "circle" ? main.orbitRadiusX : main.orbitRadiusY) : 150
        property real angle: 0
        property real circumference: currentShape === "circle" ? 
            2 * Math.PI * orbitRadiusX : 
            Math.PI * (3*(orbitRadiusX+orbitRadiusY) - Math.sqrt((3*orbitRadiusX+orbitRadiusY)*(orbitRadiusX+3*orbitRadiusY)))
        
        // 精确椭圆外切位置计算 (使用参数方程和法向量)
        x: {
            var t = angle
            var rx = orbitRadiusX
            var ry = orbitRadiusY
            // 椭圆上点坐标
            var ex = rx * Math.cos(t)
            var ey = ry * Math.sin(t)
            // 椭圆在该点的切线斜率
            var tx = -rx * Math.sin(t)
            var ty = ry * Math.cos(t)
            // 计算法向量(垂直于切线)
            var nx = ty
            var ny = -tx
            // 归一化法向量
            var len = Math.sqrt(nx*nx + ny*ny)
            nx /= len
            ny /= len
        // 根据切点模式计算位置
        container.x + container.width/2 + ex + (isOuterTangent ? 1 : -1) * nx * wheelRadius
        }
        y: {
            var t = angle
            var rx = orbitRadiusX
            var ry = orbitRadiusY
            // 椭圆上点坐标
            var ex = rx * Math.cos(t)
            var ey = ry * Math.sin(t)
            // 椭圆在该点的切线斜率
            var tx = -rx * Math.sin(t)
            var ty = ry * Math.cos(t)
            // 计算法向量(垂直于切线)
            var nx = ty
            var ny = -tx
            // 归一化法向量
            var len = Math.sqrt(nx*nx + ny*ny)
            nx /= len
            ny /= len
        // 根据切点模式计算位置
        container.y + container.height/2 + ey + (isOuterTangent ? 1 : -1) * ny * wheelRadius
        }
        radius: wheelRadius
        center: Qt.point(0, 0)
        rotationSpeed: wheelSpeed * (circumference / (2 * Math.PI * wheelRadius)) * (currentShape === "circle" ? 1 : Math.sqrt(orbitRadiusX * orbitRadiusY) / orbitRadiusX)
        holeRadius: wheelHoleRadius
        holeColor: wheelHoleColor
        holeDistance: wheelHoleDistance
        
        NumberAnimation on angle {
            from: 0
            to: 2 * Math.PI
            duration: 1000 / wheelSpeed
            loops: Animation.Infinite
            running: true
            onRunningChanged: {
                if (running) {
                    traceCanvas.lastX = wheel.mapToItem(traceCanvas, wheel.holeCenterInWheel().x, wheel.holeCenterInWheel().y).x
                    traceCanvas.lastY = wheel.mapToItem(traceCanvas, wheel.holeCenterInWheel().x, wheel.holeCenterInWheel().y).y
                }
            }
        }
    }

    Button {
        anchors.bottom: parent.bottom
        anchors.horizontalCenter: parent.horizontalCenter
        text: controlPanelWindow.visible ? "隐藏控制面板" : "打开控制面板"
        onClicked: controlPanelWindow.visible = !controlPanelWindow.visible
    }

    Window {
        id: controlPanelWindow
        width: 300
        height: 600
        title: "控制面板"
        visible: false
        x: main.x + main.width
        y: main.y

        Column {
            anchors.fill: parent
            spacing: 10
            padding: 10

            Button {
                text: "切换为圆形轨道"
                onClicked: {
                    if (currentShape !== "circle") {
                        currentShape = "circle"
                        orbitRadiusY = orbitRadiusX  // 同步半径值
                        orbitCanvas.updateOrbitPoints()
                        traceCanvas.clearTrace()
                    }
                }
            }

            Button {
                text: "切换为椭圆形轨道"
                onClicked: {
                    if (currentShape !== "ellipse") {
                        currentShape = "ellipse"
                        orbitCanvas.updateOrbitPoints()
                        traceCanvas.clearTrace()
                    }
                }
            }
        Row {
            spacing: 10
            Label { text: "轨道半径X:" }
            Slider {
                width: 100
                from: 50
                to: 900
                onValueChanged: {
                    if (orbitRadiusX !== value) {
                        orbitRadiusX = value
                        if (currentShape === "circle") {
                        orbitRadiusY = value  // 圆形时同步Y值
                        }
                        container.width = (orbitRadiusX + wheelRadius) * 2 + 20
                        orbitCanvas.updateOrbitPoints()
                        traceCanvas.clearTrace()
                        traceCanvas.width = Math.max(800, (orbitRadiusX + wheelRadius + wheelHoleDistance + wheelHoleRadius) * (currentShape === "circle" ? 3.0 : 2.5))
                    }
                }
            }
            Label { text: orbitRadiusX.toFixed(0) }
        }

        Row {
            spacing: 10
            Label { text: "轨道半径Y:" }
            Slider {
                width: 100
                from: 50
                to: 900
                value: orbitRadiusY
                enabled: currentShape === "ellipse"  // 仅椭圆时可编辑
                onValueChanged: {
                    if (orbitRadiusY !== value && currentShape === "ellipse") {
                        orbitRadiusY = value
                        container.height = (orbitRadiusY + wheelRadius) * 2 + 20
                        orbitCanvas.updateOrbitPoints()
                        traceCanvas.clearTrace()
                        traceCanvas.height = Math.max(800, (orbitRadiusY + wheelRadius + wheelHoleDistance + wheelHoleRadius) * (currentShape === "circle" ? 3.5 : 3.0))
                    }
                }
            }
            Label { text: orbitRadiusY.toFixed(0) }
        }

        Row {
            spacing: 10
            Label { text: "动轮半径:" }
            Slider {
                width: 100
                from: 20
                to: Math.min(orbitRadiusX, orbitRadiusY)
                value: wheelRadius
                onValueChanged: {
                    if (wheelRadius !== value) {
                        wheelRadius = value
                        traceCanvas.clearTrace()
                        traceCanvas.width = Math.max(800, (orbitRadiusX + wheelRadius + wheelHoleDistance + wheelHoleRadius) * (currentShape === "circle" ? 3.0 : 2.5))
                        traceCanvas.height = Math.max(800, (orbitRadiusY + wheelRadius + wheelHoleDistance + wheelHoleRadius) * (currentShape === "circle" ? 4.0 : 3.0))
                    }
                }
            }
            Label { text: wheelRadius.toFixed(0) }
        }

        Row {
            spacing: 10
            Label { text: "动轮转速:" }
            Slider {
                width: 100
                from: 0.1
                to: 5.0
                value: wheelSpeed
                onValueChanged: wheelSpeed = value
            }
            Label { text: wheelSpeed.toFixed(1) }
        }

        Row {
            spacing: 10
            Label { text: "孔半径:" }
            Slider {
                width: 100
                from: 1
                to: 30
                value: 1  // 默认值设为1
                onMoved: wheelHoleRadius = value
                onValueChanged: wheelHoleRadius = value
            }
            Label { text: wheelHoleRadius.toFixed(0) }
        }

        Row {
            spacing: 10
            Label { text: "孔颜色:" }
            ComboBox {
                width: 100
                model: ["black", "white", "red", "blue", "green", 
                       "yellow", "orange", "purple", "pink", "cyan", 
                       "magenta", "lime", "teal", "violet", "gold"]
                currentIndex: 4  // 默认选中绿色
                onActivated: wheelHoleColor = currentText
            }
        }

        Row {
            spacing: 10
            Label { text: "孔距离:" }
            Slider {
                width: 100
                from: 0
                to: wheelRadius - wheelHoleRadius
                value: wheelHoleDistance
                onValueChanged: {
                    if (wheelHoleDistance !== value) {
                        wheelHoleDistance = value
                        traceCanvas.clearTrace()
                    }
                }
            }
            Label { text: wheelHoleDistance.toFixed(0) }
        }

        Row {
            spacing: 10
            Label { text: "切点模式:" }
            Button {
                text: isOuterTangent ? "外切" : "内切"
                onClicked: {
                    isOuterTangent = !isOuterTangent
                    traceCanvas.clearTrace()
                }
            }
        }

        Button {
            text: "打印当前参数"
            onClicked: {
                console.log("当前参数值:")
                console.log("主窗口尺寸:", "width=" + main.width, "height=" + main.height)
                console.log("轨道容器尺寸:", "width=" + container.width, "height=" + container.height)
                console.log("轨道位置:", "x=" + container.x.toFixed(1), "y=" + container.y.toFixed(1))
                console.log("轨道形状:", currentShape)
                console.log("转速:", wheelSpeed)
                console.log("孔半径:", wheelHoleRadius)
                console.log("孔颜色:", wheelHoleColor)
                console.log("孔距离:", wheelHoleDistance)
                console.log("小轮圆心局部坐标:", "x=" + wheel.center.x.toFixed(1), "y=" + wheel.center.y.toFixed(1))
                console.log("小轮Rect轮廓左上角坐标:", "x=" + wheel.x.toFixed(1), "y=" + wheel.y.toFixed(1))
                console.log("小轮圆心父级坐标:", "x=" + (wheel.x + wheel.center.x).toFixed(1), "y=" + (wheel.y + wheel.center.y).toFixed(1))
                console.log("小轮尺寸:", "width="+wheel.width, "height="+wheel.height)
                console.log("小轮半径:", wheelRadius)
            }
        }

        Button {
            text: "清空轨迹"
            onClicked: traceCanvas.clearTrace()
        }
        }
    }

    Component.onCompleted: {
        orbitCanvas.requestPaint()
        traceCanvas.requestPaint()
    }

    Timer {
        id: traceTimer
        interval: 16
        running: true
        repeat: true
        triggeredOnStart: true
        onTriggered: {
            if (wheel && wheel.innerHole && wheel.innerHole.x !== undefined) {
                var ctx = traceCanvas.getContext("2d")
                ctx.fillStyle = wheel.holeColor
                ctx.strokeStyle = wheel.holeColor
                // 精确计算小孔在traceCanvas中的全局坐标
                var holeCenterInWheel = wheel.holeCenterInWheel()
                var globalPos = wheel.mapToItem(traceCanvas, holeCenterInWheel.x, holeCenterInWheel.y)
                ctx.beginPath()
                // 绘制更精确的轨迹线
                ctx.lineWidth = wheel.holeRadius * 2
                ctx.moveTo(traceCanvas.lastX, traceCanvas.lastY)
                ctx.lineTo(globalPos.x, globalPos.y)
                ctx.stroke()
                // // 在轨迹点位置绘制标记点
                // ctx.beginPath()
                // ctx.arc(globalPos.x, globalPos.y, 2, 0, Math.PI * 2)
                // ctx.fill()

                traceCanvas.lastX = globalPos.x
                traceCanvas.lastY = globalPos.y
                traceCanvas.requestPaint()
            }
        }
    }
}